/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace DslEditorPowerToy.Controls.Editors
{
    /// <summary>
    /// A sample control to demonstrate how to implement selection tracking (IMonitorSelection), 
    /// and providing selectable items (ISelectionService)
    /// for integration with a hosted editor.
    /// </summary>
    public partial class SelectionTrackerEditor : UserControl, IMonitorSelection, ISelectionService
    {
        #region Constructors
        public SelectionTrackerEditor()
        {
            InitializeComponent();

            InitialiseControls();
        }
        #endregion

        #region IMonitorSelection Members
        /// <summary>
        /// Handles change in selection from host control
        /// </summary>
        /// <param name="selectionService"></param>
        /// <param name="source"></param>
        public virtual void NotifySelectionChanged(ISelectionProvider selectionProvider, SelectionChangeSource source)
        {
            //Reset label's contents (default label stored in tag)
            this.selectedItemsLabel.Text = this.selectedItemsLabel.Tag.ToString();

            //Ensure we have the right selection change source
            if ((true == this.selectionSourceCheckBox.Checked)
                && (SelectionChangeSource.Diagram != source))
                return;

            //Ensure a selection is present
            if ((null == selectionProvider)
                || (null == selectionProvider.GetSelectedComponents()))
                return;

            //Updates the display of selected items
            StringBuilder displayText = new StringBuilder();
            ArrayList items = new ArrayList(selectionProvider.GetSelectedComponents());
            foreach (object item in items)
            {
                if (item != items[0])
                    displayText.Append(", \r\n");

                displayText.AppendFormat("{0}", item);
            }
            string selectedItems = displayText.ToString();
            if (false == string.IsNullOrEmpty(selectedItems))
                this.selectedItemsLabel.Text = selectedItems;
        }

        #endregion

        #region ISelectionService Members

        public bool GetComponentSelected(object component)
        {
            return (null != this.selectableItemsListBox.SelectedItem);
        }

        public ICollection GetSelectedComponents()
        {
            return this.selectableItemsListBox.SelectedItems;
        }

        public object PrimarySelection
        {
            get
            {
                return this.selectableItemsListBox.SelectedItem;
            }
        }

        public event EventHandler SelectionChanged;

        public event EventHandler SelectionChanging;

        public int SelectionCount
        {
            get
            {
                return this.selectableItemsListBox.SelectedItems.Count;
            }
        }

        public void SetSelectedComponents(ICollection components, SelectionTypes selectionType)
        {
            //Make no differenciation between selection types
            SetSelectedComponents(components);
        }

        public void SetSelectedComponents(ICollection components)
        {
            if ((null == components)
                || (0 == components.Count))
                return;

            foreach (object component in components)
            {
                if (component is SampleItem)
                {
                    //Find the item in the listbox
                    int index = this.selectableItemsListBox.Items.IndexOf(component as SampleItem);
                    if (index < 0)
                        continue;
                    
                    //Select item
                    this.selectableItemsListBox.SelectedItems.Add(component as SampleItem);
                }
            }
        }

        #endregion

        #region Control Handlers
        /// <summary>
        /// Handles selection change in selectable items
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void selectableItemsListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            OnSelectionChanged();
        }
        #endregion

        #region Protected Methods
        /// <summary>
        /// Raises selection changed event
        /// </summary>
        protected void OnSelectionChanged()
        {
            if (null != this.SelectionChanged)
                this.SelectionChanged(this, new EventArgs());
        }
        /// <summary>
        /// Raises selection changing event
        /// </summary>
        protected void OnSelectionChanging()
        {
            if (null != this.SelectionChanging)
                this.SelectionChanging(this, new EventArgs());
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// Initialises controls to defautl values
        /// </summary>
        private void InitialiseControls()
        {
            this.selectionSourceCheckBox.Checked = false;

            //Store default display label
            this.selectedItemsLabel.Tag = "(none)";
            this.selectedItemsLabel.Text = this.selectedItemsLabel.Tag.ToString();

            //Add sample items to list
            this.selectableItemsListBox.Items.Add(new SampleItem("SampleItem1", Color.FromKnownColor(KnownColor.Red)));
            this.selectableItemsListBox.Items.Add(new SampleItem("SampleItem2", Color.FromKnownColor(KnownColor.Green)));
            this.selectableItemsListBox.Items.Add(new SampleItem("SampleItem3", Color.FromKnownColor(KnownColor.Blue)));
        }
        #endregion

    }

    /// <summary>
    /// Class to represent some sample selectable items
    /// </summary>
    public class SampleItem
    {
        private string _name = string.Empty;
        private Font _font = SystemFonts.DefaultFont;
        private Size _size = new Size();
        private Color _backColor = Color.FromKnownColor(KnownColor.Control);

        #region Constructors
        public SampleItem(string name, Color backColor)
        {
            this._name = name;
            this._font = SystemFonts.DefaultFont;
            this._size = new Size();
            this._backColor = backColor;
        }
        #endregion

        #region Public Properties
        public string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                this._name = value;
            }
        }
        public Font Font
        {
            get
            {
                return this._font;
            }
        }
        public Size Size
        {
            get
            {
                return this._size;
            }
            set
            {
                this._size = value;
            }
        }
        public Color BackColor
        {
            get
            {
                return this._backColor;
            }
            set
            {
                this._backColor = value;
            }
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Returns the string representation of the class
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("{0} ({1})", this._name, base.ToString());
        }
        #endregion
    }
}
